package com.zhiwen.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ配置类
 */
@Configuration
@EnableRabbit
public class RabbitMQConfig {
    
    // 通用通知交换机
    public static final String NOTIFICATION_EXCHANGE = "notification.exchange";
    
    // 通知主题交换机（按类型分发）
    public static final String NOTIFICATION_TOPIC_EXCHANGE = "notification.topic.exchange";
    
    // 通用通知队列
    public static final String NOTIFICATION_QUEUE = "notification.queue";
    
    // 不同类型的通知队列
    public static final String QUESTION_NOTIFICATION_QUEUE = "notification.question.queue";
    public static final String ANSWER_NOTIFICATION_QUEUE = "notification.answer.queue";
    public static final String COMMENT_NOTIFICATION_QUEUE = "notification.comment.queue";
    public static final String SYSTEM_NOTIFICATION_QUEUE = "notification.system.queue";
    public static final String LIKE_NOTIFICATION_QUEUE = "notification.like.queue";
    public static final String FOLLOW_NOTIFICATION_QUEUE = "notification.follow.queue";
    
    // 通用通知路由键
    public static final String NOTIFICATION_ROUTING_KEY = "notification.routing.key";
    
    // 不同类型的通知路由键前缀
    public static final String NOTIFICATION_TOPIC_PREFIX = "notification.";
    
    // 死信交换机和队列
    public static final String DEAD_LETTER_EXCHANGE = "notification.dead.letter.exchange";
    public static final String DEAD_LETTER_QUEUE = "notification.dlq";
    public static final String DEAD_LETTER_ROUTING_KEY = "notification.dead.letter";
    
    // 添加批量通知队列常量
    // 批量通知队列
    public static final String BATCH_NOTIFICATION_QUEUE = "notification.batch.queue";
    
    // 批量通知路由键
    public static final String BATCH_NOTIFICATION_ROUTING_KEY = "notification.batch";
    
    /**
     * 声明通用通知交换机
     */
    @Bean
    public DirectExchange notificationExchange() {
        return new DirectExchange(NOTIFICATION_EXCHANGE);
    }
    
    /**
     * 声明通知主题交换机（支持按类型分发）
     */
    @Bean
    public TopicExchange notificationTopicExchange() {
        return new TopicExchange(NOTIFICATION_TOPIC_EXCHANGE);
    }
    
    /**
     * 声明死信交换机
     */
    @Bean
    public DirectExchange deadLetterExchange() {
        return new DirectExchange(DEAD_LETTER_EXCHANGE);
    }
    
    /**
     * 声明死信队列
     */
    @Bean
    public Queue deadLetterQueue() {
        return QueueBuilder.durable(DEAD_LETTER_QUEUE)
                .build();
    }
    
    /**
     * 配置队列的死信属性
     * 修改所有队列的构建方法，添加死信配置
     */
    @Bean
    public Queue notificationQueue() {
        return QueueBuilder.durable(NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明问题相关通知队列
     */
    @Bean
    public Queue questionNotificationQueue() {
        return QueueBuilder.durable(QUESTION_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明回答相关通知队列
     */
    @Bean
    public Queue answerNotificationQueue() {
        return QueueBuilder.durable(ANSWER_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明评论相关通知队列
     */
    @Bean
    public Queue commentNotificationQueue() {
        return QueueBuilder.durable(COMMENT_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明系统通知队列
     */
    @Bean
    public Queue systemNotificationQueue() {
        return QueueBuilder.durable(SYSTEM_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明点赞通知队列
     */
    @Bean
    public Queue likeNotificationQueue() {
        return QueueBuilder.durable(LIKE_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明关注通知队列
     */
    @Bean
    public Queue followNotificationQueue() {
        return QueueBuilder.durable(FOLLOW_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 声明批量通知队列
     */
    @Bean
    public Queue batchNotificationQueue() {
        return QueueBuilder.durable(BATCH_NOTIFICATION_QUEUE)
                .withArgument("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY)
                .withArgument("x-message-ttl", 86400000) // 24小时过期
                .build();
    }
    
    /**
     * 问题通知队列绑定
     * 使用精确匹配的路由键，避免与其他队列重复接收消息
     */
    @Bean
    public Binding questionNotificationBinding() {
        return BindingBuilder.bind(questionNotificationQueue())
                .to(notificationTopicExchange())
                .with(NOTIFICATION_TOPIC_PREFIX + "question.*");
    }
    
    /**
     * 回答通知队列绑定
     * 使用精确匹配的路由键，避免与其他队列重复接收消息
     */
    @Bean
    public Binding answerNotificationBinding() {
        return BindingBuilder.bind(answerNotificationQueue())
                .to(notificationTopicExchange())
                .with(NOTIFICATION_TOPIC_PREFIX + "answer.*");
    }
    
    /**
     * 评论通知队列绑定
     * 使用精确匹配的路由键，避免与其他队列重复接收消息
     */
    @Bean
    public Binding commentNotificationBinding() {
        return BindingBuilder.bind(commentNotificationQueue())
                .to(notificationTopicExchange())
                .with(NOTIFICATION_TOPIC_PREFIX + "comment.*");
    }
    
    /**
     * 系统通知队列绑定
     * 使用精确匹配的路由键，避免与其他队列重复接收消息
     */
    @Bean
    public Binding systemNotificationBinding() {
        return BindingBuilder.bind(systemNotificationQueue())
                .to(notificationTopicExchange())
                .with(NOTIFICATION_TOPIC_PREFIX + "system.*");
    }
    
    /**
     * 死信队列绑定
     */
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue())
                .to(deadLetterExchange())
                .with(DEAD_LETTER_ROUTING_KEY);
    }
    
    /**
     * 点赞通知队列绑定
     * 使用精确匹配的路由键，避免与其他队列重复接收消息
     */
    @Bean
    public Binding likeNotificationBinding() {
        return BindingBuilder.bind(likeNotificationQueue())
                .to(notificationTopicExchange())
                .with(NOTIFICATION_TOPIC_PREFIX + "like.*");
    }
    
    /**
     * 关注通知队列绑定
     * 使用精确匹配的路由键，避免与其他队列重复接收消息
     */
    @Bean
    public Binding followNotificationBinding() {
        return BindingBuilder.bind(followNotificationQueue())
                .to(notificationTopicExchange())
                .with(NOTIFICATION_TOPIC_PREFIX + "follow.*");
    }
    
    /**
     * 批量通知队列绑定
     */
    @Bean
    public Binding batchNotificationBinding() {
        return BindingBuilder.bind(batchNotificationQueue())
                .to(notificationExchange())
                .with(BATCH_NOTIFICATION_ROUTING_KEY);
    }
    
    /**
     * 消息转换器
     */
    @Bean
    public Jackson2JsonMessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }
    
    /**
     * 配置RabbitTemplate
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter());
        
        // 设置消息确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                // 消息发送失败处理
                System.err.println("消息发送到交换机失败: " + cause);
            }
        });
        
        // 设置消息返回回调
        rabbitTemplate.setReturnsCallback(returned -> {
            System.err.println("消息从交换机路由到队列失败: exchange=" + returned.getExchange() 
                    + ", routingKey=" + returned.getRoutingKey()
                    + ", replyCode=" + returned.getReplyCode()
                    + ", replyText=" + returned.getReplyText());
        });
        
        return rabbitTemplate;
    }
} 